package com.pi.pro.xcmg.am.was.fac.service;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.monitor.base.config.MonitorConfigProperties;
import com.pi.monitor.base.config.props.MonitorConfigStorageProperties;
import com.pi.monitor.base.dto.*;
import com.pi.monitor.common.MonitorConstants;
import com.pi.monitor.common.StorageConstants;
import com.pi.monitor.entity.TmmBasViewItem;
import com.pi.monitor.service.ViewItemService;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.entity.TwaInventoryDetails;
import com.pi.wms.entity.TwmBasLocation;
import com.pi.wms.service.InventoryDetailsService;
import com.pi.wms.service.LocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 *
 */
@Service
public class StorageViewService {

    @Autowired
    protected MonitorConfigProperties monitorConfigProperties;

    @Autowired
    private InventoryDetailsService inventoryService;

    @Autowired
    private LocationService locationService;

    @Autowired
    private ViewItemService itemService;

    private int maxLane   = 1;
    private int maxColumn = 1;
    private int maxLayer  = 1;
    private int depth = 1;


    @SuppressWarnings("unused")
    private String devMode="N";

    private static Long idseq=100000L;
    private static Map<String,List<LocationStorage>> lines=new HashMap<String,List<LocationStorage>>();
    private static Map<String,Map<String,LocationLayer>> lineLayers=new HashMap<String,Map<String,LocationLayer>>();

    public static Map<String,LocationLineView> linesMapping=new HashMap<>();

    private static Map<String,String> damages=new HashMap<String,String>();

    private Cache<String, LocationLane> summaryCache= CacheBuilder.newBuilder().expireAfterWrite(120, TimeUnit.MINUTES).build();

    @PostConstruct
    public void install(){
        MonitorConfigStorageProperties storageProperties;
        if ((monitorConfigProperties!=null) && (monitorConfigProperties.getStorage()!=null)){
            storageProperties=monitorConfigProperties.getStorage();
            if (storageProperties.getMaxLane()!=null){
                this.maxLane=storageProperties.getMaxLane();
            }
            if (storageProperties.getMaxColumn()!=null){
                this.maxColumn=storageProperties.getMaxColumn();
            }
            if (storageProperties.getMaxLayer()!=null){
                this.maxLayer=storageProperties.getMaxLayer();
            }
            if (storageProperties.getDepth()!=null){
                this.depth=storageProperties.getDepth();
            }
            if ((storageProperties!=null) &&(storageProperties.getDamages()!=null)){
                for(Map.Entry<String, String> entry:storageProperties.getDamages().entrySet()){
                    if (entry.getKey()!=null){
                        damages.put(entry.getKey().trim().toUpperCase(), entry.getValue());
                    }
                }
            }
        }
        installLocations();
        //TODO:HU/202012
        //damages init here
    }


    /**
     * LINE库存清单: CELL模式
     * 为界面显示方便,返回的数据,按层倒排序,即:
     *   Data[0][]=L[09][]
     *   ...
     *   Data[9][]=L[01][]
     */
    public LocationCell[][] listAll(String lineNumber) {
        //this.random();
        Map<String,LocationLayer> layers=lineLayers.get(lineNumber);
        if (layers==null){
            return null;
        }
        LocationLayer layer=null;
        LocationCell cell=null;
        String layercode="";
        LocationCell[][] data=new LocationCell[this.maxLayer][this.maxColumn];
        for(int i=1;i<=this.maxLayer;i++){
            layercode=String.format("%02d", i);
            for (int j=1;j<=this.maxColumn;j++){
                layer=layers.get(layercode);
                cell=layer.get(j);
                if (cell!=null){
                    data[this.maxLayer-i][j-1]=cell;
                    cell.calculateStyleClass(this.depth);
                }
            }
        }
        return data;
    }

    /**
     *  LINE库存清单: LOC模式
     */
    public LocationCell[][] listAll(String lineCode, boolean flex) {
        if (!flex){
            return this.listAll(lineCode);
        }
        if (StringUtils.isNullOrBlank(lineCode)){
            return new LocationCell[0][0];
        }
        LocationLineView line = linesMapping.get(lineCode);
        /**
         if (line!=null){
         return line.getData();
         }
         **/
        TmmBasViewItem lineview=null;
        if ((line==null) || (!line.hasInstalled())){
            lineview=this.itemService.findByCode(lineCode);
            if (lineview==null){
                return new LocationCell[0][0];
            }
            line = this.installLocations(lineview);
            if (line.getSize()>0){
                line.setInstalled();
            }
            linesMapping.put(lineCode,line);
        }
        this.fill(line);
        return line.getData();
    }

    /**
     *  LINE库存清单: LINE+LAYER模式
     */
    public LocationCell[] listAll(String lineNumber,String layerNumber) {
        this.random();
        Map<String,LocationLayer> layers=lineLayers.get(lineNumber);
        if (layers==null){
            return null;
        }
        LocationLayer layer=null;
        LocationCell cell=null;
        String layercode=StringUtils.leftPad(layerNumber, 2, "0");
        layer=layers.get(layercode);
        if (layer==null){
            return null;
        }
        LocationCell[] data=new LocationCell[this.maxColumn];
        for (int j=1;j<=this.maxColumn;j++){
            cell=layer.get(j);
            if (cell!=null){
                data[j-1]=cell;
                cell.calculateStyleClass(this.depth);
            }
        }
        return data;
    }

    /**
     * 按排(CELL模式)汇总
     */
    public List<LineStorageSummary> lineSummary(){
        List<LineStorageSummary> data=new ArrayList<LineStorageSummary>();
        LineStorageSummary sum=null;
        //
        this.random();
        //
        int linenum=0;
        String linecode="";
        int totalCount=0;
        int usingCount=0;
        int containCount=0;
        int freeCount=0;
        int holdCount=0;
        int demCount=0;

        for(List<LocationStorage> line:lines.values()){
            totalCount=0;
            usingCount=0;
            containCount=0;
            freeCount=0;
            holdCount=0;
            demCount=0;

            for(LocationStorage loc:line){
                linenum=loc.getLine();
                linecode=loc.getViewitemCode();
                totalCount++;

                if (loc.getStatus()==null){
                    freeCount++;
                    continue;
                }
                if (damages.containsKey(loc.getLocationCode())){
                    demCount++;
                    continue;
                }
                if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_USING)){
                    if (!loc.isContainer()){
                        usingCount++;
                    }else{
                        containCount++;
                    }
                }else if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_FREE)){
                    freeCount++;
                }else if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_HOLD)){
                    holdCount++;
                }else{
                    freeCount++;
                }

            }
            BigDecimal total=new BigDecimal(totalCount);
            sum=new LineStorageSummary(linenum,linecode,
                    new BigDecimal(usingCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                    new BigDecimal(containCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                    new BigDecimal(freeCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                    new BigDecimal(holdCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                    new BigDecimal(demCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN));
            data.add(sum);
        }

        return data;
    }

    /**
     * 按巷道汇总
     */
    public List<LaneStorageSummary> laneSummary(int size){
        List<LaneStorageSummary> laneSumms=new ArrayList<LaneStorageSummary>();
        if (size<=0){
            return laneSumms;
        }
        LocationLane[] lanes=this.laneSummarying(size);
        if ((lanes==null)||(lanes.length==0)){
            return laneSumms;
        }
        LaneStorageSummary laneSumm=null;
        for (LocationLane lane:lanes){
            if (lane==null){
                continue;
            }
            laneSumm=new LaneStorageSummary(lane);
            laneSumms.add(laneSumm);
        }
        return laneSumms;
    }

    /**
     * 汇总整仓库/LINE(CELL)方式
     */
    public LineStorageSummary summary(){
        LineStorageSummary sum=null;
        //
        int linenum=0;
        String linecode="ALL";
        int totalCount=0;
        int usingCount=0;
        int containCount=0;
        int freeCount=0;
        int holdCount=0;
        int demCount=0;

        for(List<LocationStorage> line:lines.values()){
            for(LocationStorage loc:line){
                //linenum=loc.getLine();
                //linecode=loc.getLineCode();
                totalCount++;

                if (loc.getStatus()==null){
                    freeCount++;
                    continue;
                }
                if (damages.containsKey(loc.getLocationCode())){
                    demCount++;
                    continue;
                }
                if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_USING)){
                    if (!loc.isContainer()){
                        usingCount++;
                    }else{
                        containCount++;
                    }
                }else if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_FREE)){
                    freeCount++;
                }else if (loc.getStatus().equals(StorageConstants.STORAGE_STATUS_HOLD)){
                    holdCount++;
                }else{
                    freeCount++;
                }
            }
        }
        BigDecimal total=new BigDecimal(totalCount);
        sum=new LineStorageSummary(linenum,linecode,
                new BigDecimal(usingCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                new BigDecimal(containCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                new BigDecimal(freeCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                new BigDecimal(holdCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN),
                new BigDecimal(demCount).divide(total,4,BigDecimal.ROUND_HALF_DOWN));
        return sum;
    }

    /**
     * 汇总整仓库/LANE方式
     */
    public LaneStorageSummary summary(int size){
        LocationLane lanesumm=new LocationLane("ALL", 0);
        if (size<=0){
            return new LaneStorageSummary(lanesumm);
        }
        LocationLane[] lanes=this.laneSummarying(size);
        if ((lanes==null) || (lanes.length==0)){
            return new LaneStorageSummary(lanesumm);
        }
        int totalCount=0;
        int usingCount=0;
        int containCount=0;
        int freeCount=0;
        int demCount=0;
        int holdCount=0;
        for (LocationLane lane:lanes){
            if (lane==null){
                continue;
            }
            if (lane.getTotal()<=0){
                continue;
            }
            totalCount=totalCount+lane.getTotal();
            usingCount=usingCount+lane.getUsingTotal();
            containCount=containCount+lane.getContainTotal();
            freeCount=freeCount+lane.getFreeTotal();
            demCount=demCount+lane.getDamageTotal();
            holdCount=holdCount+lane.getHoldTotal();
        }
        lanesumm.summay(totalCount,usingCount,containCount,freeCount,demCount,holdCount);
        return new LaneStorageSummary(lanesumm);
    }



    /*******************************************************************************************************
     *  PRIVATE/install
     ******************************************************************************************************/
    private void installLocations(){
        for(int i=1;i<=this.maxLane*2;i++){
            installLocations(i);
        }
        fillLayers();
    }

    private void installLocations(int line){
        List<LocationStorage> data=new ArrayList<LocationStorage>();
        LocationStorage loc=null;
        String loccode="";
        String linecode="";
        int lane = 1;
        if (line>=3){
            lane=2;
        }
        //左边-浅库位
        for(int i=1; i<=this.maxColumn;i++){
            for(int j=1;j<=this.maxLayer;j++){
                loccode=String.format("RA%02d-%03d-%03d", line, i, j);
                linecode=String.format("L%02d/R%02d", line, lane);
                loc=new LocationStorage(idseq++,loccode,linecode,line,i,j, StorageConstants.STORAGE_DEEP_FRONT,StorageConstants.STORAGE_STATUS_FREE);
                data.add(loc);
            }
        }

        /**
        //左边-深库位
        if (this.depth>1){
            for(int i=1; i<=this.maxColumn;i++){
                for(int j=1;j<=this.maxLayer;j++){
                    loccode=String.format("R%02d02%03d%02d", lane,i,j);
                    linecode=String.format("L%02d/R%02d", line,lane);
                    loc=new LocationStorage(idseq++,loccode,linecode,line,i,j,StorageConstants.STORAGE_DEEP_DEEP,StorageConstants.STORAGE_STATUS_FREE);
                    data.add(loc);
                }
            }
        }
        lines.put(String.valueOf(line), data);

        line=lane*2;
        data=new ArrayList<LocationStorage>();
        //右边-浅库位
        for(int i=1; i<=this.maxColumn;i++){
            for(int j=1;j<=this.maxLayer;j++){
                loccode=String.format("R%02d03%03d%02d", lane,i,j);
                linecode=String.format("L%02d/R%02d", line,lane);
                loc=new LocationStorage(idseq++,loccode,linecode,line,i,j,StorageConstants.STORAGE_DEEP_FRONT,StorageConstants.STORAGE_STATUS_FREE);
                data.add(loc);
            }
        }
        //左边-深库位
        if (this.depth>1){
            //if (StorageConstants.STORAGE_DEEP_LAYOUT_SINGLE.compareToIgnoreCase("Y")!=0){
            for(int i=1; i<=this.maxColumn;i++){
                for(int j=1;j<=this.maxLayer;j++){
                    loccode=String.format("R%02d04%03d%02d", lane,i,j);
                    linecode=String.format("L%02d/R%02d", line,lane);
                    loc=new LocationStorage(idseq++,loccode,linecode,line,i,j,StorageConstants.STORAGE_DEEP_DEEP,StorageConstants.STORAGE_STATUS_FREE);
                    data.add(loc);
                }
            }
        }
         **/
        lines.put(String.valueOf(line), data);
    }

    private LocationLineView installLocations(TmmBasViewItem lineView){
        LocationLineView line=null;
        if (lineView==null){
            return line;
        }
        String m=check(lineView);
        if (!StringUtils.isNullOrBlank(m)){
            return line;
        }
        List<LocationStorage> data=new ArrayList<LocationStorage>();
        LocationStorage loc=null;
        String loccode="";
        int linenum=1;
        String linecode="";
        linenum=lineView.getValue().intValue();
        String prefix="RA";
        int columnSize = lineView.getCellsYSize().intValue();
        int layerSize = lineView.getCellsZSize().intValue();

        int lanenum=1;
        if (linenum>=3){
            lanenum=2;
        }
        //
        int depthval=StorageConstants.STORAGE_DEEP_FRONT_VAL;
        String depthcode=StorageConstants.STORAGE_DEEP_FRONT;
        if ( (lineView.getCellsFamilyCode()!=null) && (lineView.getCellsFamilyCode().equalsIgnoreCase(StorageConstants.STORAGE_LINE_DEEP_DEEP))){
            depthcode=StorageConstants.STORAGE_DEEP_DEEP;
            depthval=StorageConstants.STORAGE_DEEP_DEEP_VAL;;
        }
        line=new LocationLineView(lineView.getDivisionId(), lineView.getZoneId(), lineView.getCode(),linenum,columnSize,layerSize);
        for(int i=1; i<=columnSize;i++){
            for(int j=1;j<=layerSize;j++){
                loccode=String.format("%s%02d-%03d-%03d", prefix,linenum, i, j);
                linecode=String.format("L%02d/R%02d", linenum, lanenum);
                loc=new LocationStorage(idseq++,loccode,linecode,linenum,i,j, depthcode,StorageConstants.STORAGE_STATUS_FREE);
                data.add(loc);
                line.add(loc,i,j,depthval);
            }
        }
        return line;
    }

    private void fillLayers(){
        Map<String,LocationLayer> layers=null;
        LocationLayer layer=null;
        List<LocationStorage> list=null;
        int layernum=0;
        String layercode="";
        for (Map.Entry<String,List<LocationStorage>> entry:lines.entrySet()){
            layers=new TreeMap<String,LocationLayer>();
            list=entry.getValue();
            for(LocationStorage ls:list){
                layernum=ls.getLayer();
                layercode=String.format("%02d", ls.getLayer());
                layer=layers.get(layercode);
                if (layer==null){
                    layer=new LocationLayer(layernum);
                    layers.put(layercode, layer);
                }
                layer.put(ls);
            }
            lineLayers.put(entry.getKey(), layers);
        }

    }


    /*******************************************************************************************************
     *  PRIVATE/found
     ******************************************************************************************************/

    private List<LocationStorage> findAll(String lineNumber) {
        this.random();
        List<LocationStorage> data=lines.get(lineNumber);
        return data;
    }

    private List<LocationStorage> findAll(String lineNumber,String layerNumber) {
        this.random();
        List<LocationStorage> data=lines.get(lineNumber);
        return data;
    }



    /*******************************************************************************************************
     *  PRIVATE/Tools
     ******************************************************************************************************/

    private void randomOnDev(){
        int val=50;
        for(List<LocationStorage> line:lines.values()){
            for(LocationStorage loc:line){
                val=(int)(1+Math.random()*(100-0+1));
                loc.setStatus(StorageConstants.STORAGE_STATUS_FREE);
                if ((val%3)==0){
                    loc.setStatus(StorageConstants.STORAGE_STATUS_USING);
                }
                if ((val%20)==0){
                    loc.setStatus(StorageConstants.STORAGE_STATUS_HOLD);
                }
            }
        }
    }

    private void random(){
        Map<String,String> materials=new HashMap<String,String>();
        Map<String,String> stocks=this.fill(materials);
        String status=null;
        for(List<LocationStorage> line:lines.values()){
            for(LocationStorage loc:line){
                status=stocks.get(loc.getLocationCode());
                loc.setMaterialid(materials.get(loc.getLocationCode()));
                if ((status==null) || (status.equals(""))){
                    status=StorageConstants.STORAGE_STATUS_FREE;
                }
                loc.setStatus(status);
            }
        }
    }

    private String check(TmmBasViewItem lineView) {
        String m="";
        if (lineView==null){
            return "lineview is null";
        }
        if (!StorageConstants.STORAGE_LINE_VIEW_TYPE.equalsIgnoreCase(lineView.getType())){
            return "invalidate item type";
        }
        if ((lineView.getCellsXSize()==null) || (lineView.getCellsXSize().compareTo(BigDecimal.ZERO))<=0){
            return "invalidate item line number";
        }
        if ((lineView.getRefId()==null)||(lineView.getRefId()<=0)){
            return "invalidare item lane number";
        }
        if ((lineView.getCellsYSize()==null) || (lineView.getCellsYSize().compareTo(BigDecimal.ZERO))<=0){
            return "invalidate item column size";
        }
        if ((lineView.getCellsZSize()==null) || (lineView.getCellsZSize().compareTo(BigDecimal.ZERO))<=0){
            return "invalidate item layer size";
        }
        if (StringUtils.isNullOrBlank(lineView.getGroup())){
            return "invalidate item location prefix";
        }
        return m;
    }

    private boolean check(TwaInventoryDetails data){
        boolean checked=false;
        if (data==null){
            return checked;
        }
        if ((data.getLocCode()==null) || (data.getLocCode().equals(""))){
            return checked;
        }
        if (data.getQty().compareTo(BigDecimal.ZERO)<=0){
            return checked;
        }
        checked=true;
        return checked;
    }

    private boolean isContainer(TwaInventoryDetails storage){
        if (storage==null){
            return false;
        }
        if (storage.getMaterialId()==null){
            return false;
        }
        String matid=String.valueOf(storage.getMaterialId());
        if ((!matid.equals(StorageConstants.MATERIAL_PALLET))
                && (!matid.equals(StorageConstants.MATERIAL_CARTON))){
            return false;
        }
        return true;
    }

    private void clean(LocationLineView line, Map<String,TwmBasLocation> locations){
        if  ((line==null) ||(line.getSize()<=0)){
            return;
        }
        boolean checkflag=true;
        if ((locations==null) || (locations.size()==0)){
            checkflag=false;
        }
        Collection<LocationStorage> storages=line.listAll();
        TwmBasLocation loc=null;
        for (LocationStorage st:storages){
            if (st==null){
                continue;
            }
            st.clean();
            st.setStatus(StorageConstants.STORAGE_STATUS_FREE);
            if (!checkflag){
                continue;
            }
            loc=locations.get(st.getLocationCode());
            if ((loc==null) || (WmsConstants.LOCATION_STATUS_DAMAGE.equalsIgnoreCase(loc.getStatus()))){
                st.setStatus(StorageConstants.STORAGE_STATUS_DAMAGE);
            }
            line.calculateStyleClass(st);
        }
    }

    private Map<String,String> fill(Map<String,String> materials){
        Map<String,String> stockes=new HashMap<String,String>();
        List<TwaInventoryDetails> datas=Lists.newArrayList(this.inventoryService.findAll());
        /**
         TaInvDetails data=null;
         Iterator<TaInvDetails> it=datas.iterator();
         while(it.hasNext()){
         data=it.next();
         if (!check(data)){
         continue;
         }
         stockes.put(data.getLocCode(), StorageConstants.STORAGE_STATUS_USING);
         if (data.getStatus()==null){
         continue;
         }
         if (data.getStatus().equals(WmsConstants.STORAGE_STATUS_LOCK)){
         stockes.put(data.getLocCode(), StorageConstants.STORAGE_STATUS_HOLD);
         }
         }
         **/
        for(TwaInventoryDetails d:datas){
            if (!check(d)){
                continue;
            }
            if (materials!=null){
                materials.put(d.getLocCode(), String.valueOf(d.getMaterialId()));
            }
            stockes.put(d.getLocCode(), StorageConstants.STORAGE_STATUS_USING);
            if (d.getStatus()==null){
                continue;
            }
            if (d.getStatus().equals(WmsConstants.STORAGE_STATUS_LOCK)){
                stockes.put(d.getLocCode(), StorageConstants.STORAGE_STATUS_HOLD);
            }
        }

        for(String code:damages.keySet()){
            if (code==null){
                continue;
            }
            if (code.equals("")){
                continue;
            }
            stockes.put(code, StorageConstants.STORAGE_STATUS_DAMAGE);
        }
        return stockes;
    }

    private void fill(LocationLineView line) {
        if ((line==null) || (line.getLinenumber()<=0) || (line.getData()==null) || (line.getSize()<=0)){
            return;
        }
        List<TwaInventoryDetails> storages = Lists.newArrayList(this.inventoryService.findByLineNumber(line.getLinenumber()));
        if ((storages==null) || (storages.size()==0)){
            return;
        }
        List<TwmBasLocation> locations = Lists.newArrayList(this.locationService.findByLineNumber(line.getLinenumber()));
        Map<String,TwmBasLocation> locationMap=new HashMap<String,TwmBasLocation>();
        if (locations!=null){
            locations.forEach((x)->locationMap.put(x.getCode(),x));
        }
        this.clean(line,locationMap);
        LocationStorage storage=null;
        TwmBasLocation loc=null;
        for (TwaInventoryDetails data:storages){
            if (data==null){
                continue;
            }
            storage=line.get(data.getLocCode());
            if (storage==null){
                continue;
            }
            storage.clean();
            if (data.getMaterialId()!=null){
                storage.setMaterialid(String.valueOf(data.getMaterialId()));
                storage.setQuantity(data.getQty());
                storage.setUom(CodesConstants.UOM_EACH);
                storage.setContainnumber(data.getContainNumber());
            }
            storage.setStatus(StorageConstants.STORAGE_STATUS_FREE);
            if  ((WmsConstants.STORAGE_STATUS_AVAILABLE.equalsIgnoreCase(data.getStatus()))
                    || (MonitorConstants.STORAGE_STATUS_AVAILABLE_VALUE.equalsIgnoreCase(data.getStatus()))){
                storage.setStatus(StorageConstants.STORAGE_STATUS_USING);
            }
            loc=locationMap.get(storage.getLocationCode());
            if (loc==null){
                storage.setStatus(StorageConstants.STORAGE_STATUS_DAMAGE);
            }
            if (loc!=null){
                if (WmsConstants.LOCATION_STATUS_DAMAGE.equalsIgnoreCase(loc.getStatus())){
                    storage.setStatus(StorageConstants.STORAGE_STATUS_DAMAGE);
                }
                if (WmsConstants.LOCATION_STATUS_LOCKED.equalsIgnoreCase(loc.getStatus())){
                    storage.setHoldStatus(CodesConstants.COMMON_FLAG_YES);
                }
            }
            line.calculateStyleClass(storage);
        }
        if (damages!=null){
            for(String code:damages.keySet()){
                if (code==null){
                    continue;
                }
                if (StringUtils.isNullOrBlank(code)){
                    continue;
                }
                storage=line.get(code);
                if (storage==null){
                    continue;
                }
                storage.setStatus(StorageConstants.STORAGE_STATUS_DAMAGE);
                line.calculateStyleClass(storage);
            }
        }

    }

    private int totalOfLane(int lanenum){
        //blank
        int total=0;
        Iterable<TmmBasViewItem> lineviews=this.itemService.findAll();
        if (lineviews!=null){
            for (TmmBasViewItem item:lineviews){
                total=total+totalOfLane(item,lanenum);
            }
        }
        return total;
    }
    private int totalOfLane(TmmBasViewItem item, int lanenum){
        int total=0;
        String m=this.check(item);
        if (!StringUtils.isNullOrBlank(m)){
            return total;
        }
        if (item.getRefId().intValue()==lanenum){
            total=item.getCellsYSize().intValue()*item.getCellsZSize().intValue();
        }
        return total;
    }

    private Map<String,TwaInventoryDetails> mapOfLocaitonInventories(){
        Map<String,TwaInventoryDetails> map = new HashMap<String,TwaInventoryDetails>();

        Iterable<TwaInventoryDetails> inventories=this.inventoryService.findAll();
        if (inventories==null){
            return map;
        }
        for (TwaInventoryDetails inv:inventories){
            if (inv==null){
                continue;
            }
            if (inv.getQty()==null){
                continue;
            }
            if (inv.getMaterialId()==null){
                continue;
            }
            if (inv.getQty().compareTo(BigDecimal.ZERO)<=0){
                continue;
            }
            if (StringUtils.isNullOrBlank(inv.getLocCode())){
                continue;
            }
            map.put(inv.getLocCode(),inv);
        }
        return map;
    }

    private LocationLane[] laneSummarying(int size){
        if (size<=0){
            return null;
        }
        LocationLane[] lanes=new LocationLane[size];
        //
        this.random();
        //
        int lanenum=0;
        String lanecode="";
        int totalCount=0;
        int usingCount=0;
        int containCount=0;
        int freeCount=0;
        int holdCount=0;
        int demCount=0;

        //total/lineview
        for (int i=0;i<size;i++){
            lanenum=i+1;
            lanecode=String.format("R%02d",lanenum);
            lanes[i]= this.summaryCache.getIfPresent(lanecode);
            if (lanes[i]==null){
                lanes[i]=new LocationLane(lanecode,lanenum);
                lanes[i].addTotal(this.totalOfLane(lanenum));
                this.summaryCache.put(lanecode,lanes[i]);
            }
        }

        //total//inventory
        Map<String,TwaInventoryDetails> inventoryLocationsMap = this.mapOfLocaitonInventories();
        TwaInventoryDetails storage=null;

        List<TwmBasLocation> locations=null;
        for (LocationLane lane:lanes){
            totalCount=0;
            usingCount=0;
            containCount=0;
            freeCount=0;
            demCount=0;
            holdCount=0;
            lanecode=lane.getLanecode();
            lanenum=lane.getLanenumber();
            totalCount=lane.getTotal();
            //
            locations=this.locationService.findByLaneNumber(lanenum);
            if ((totalCount<=0) ||(locations==null) || (locations.size()==0)){
                continue;
            }
            for (TwmBasLocation loc:locations){
                if (loc==null){
                    continue;
                }
                //
                if (WmsConstants.LOCATION_STATUS_DAMAGE.equalsIgnoreCase(loc.getStatus())){
                    demCount=demCount+1;
                    continue;
                }
                if (WmsConstants.LOCATION_STATUS_LOCKED.equalsIgnoreCase(loc.getStatus())){
                    holdCount=holdCount+1;
                }
                //
                storage=inventoryLocationsMap.get(loc.getCode());
                if (storage==null){
                    freeCount=freeCount+1;
                    continue;
                }
                if (!this.isContainer(storage)){
                    usingCount=usingCount+1;
                }else {
                    containCount=containCount+1;
                }
            }
            //
            demCount=totalCount-usingCount-containCount-freeCount+demCount;
            lane.summay(totalCount,usingCount,containCount,freeCount,demCount,holdCount);
            //
        }
        return lanes;
    }
}
